package com.smilive.start.netty.netty;

import com.smilive.start.netty.utils.ByteBufUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;

/**
 * @program: netty
 * @Date: 2022-01-05 16:28
 * @Author: smilive
 * @Description:ByteBuf切片是【零拷贝】的体现之一,
 * 对原始 ByteBuf 进行切片成多个 ByteBuf，切片后的 ByteBuf 并没有发生内存复制,
 * 还是使用原始 ByteBuf 的内存，切片后的 ByteBuf 维护独立的 read，write 指针
 *
 * 得到分片后的buffer后，要调用其retain方法，使其内部的引用计数加一。避免原ByteBuf释放，导致切片buffer无法使用
 *
 * 修改原ByteBuf中的值，也会影响切片后得到的ByteBuf
 */
public class ByteBufSlice {

    public static void main(String[] args) {
        ByteBuf buffer = ByteBufAllocator.DEFAULT.buffer(16);

        buffer.writeBytes(new byte[]{1,2,3,4,5,6,7,8});

        //用slice(零拷贝) 分成两部分
        ByteBuf slice1 = buffer.slice(0, 4);
        ByteBuf slice2 = buffer.slice(4, 4);

        ByteBufUtil.log(slice1);
        ByteBufUtil.log(slice2);

        // 需要让分片的buffer引用计数加一
        // 避免原Buffer释放导致分片buffer无法使用
        slice1.retain();
        slice2.retain();
        //释放原buffer
        buffer.release();
        System.out.println("===========释放原buffer后===========");
        ByteBufUtil.log(slice1);
        ByteBufUtil.log(slice2);

        // 更改原始buffer中的值
        System.out.println("===========修改原buffer中的值===========");
        buffer.setByte(0,5);

        System.out.println("===========打印slice1===========");
        ByteBufUtil.log(slice1);
    }
}
